﻿using System;
using System.Collections;
using System.Collections.Generic;
using ImageEffects;
using UnityEngine;
using WorldMapBase;
using WorldMapBase.Tile.Pool;
using Yoozoo.Managers.ResourceManagerV2.Runtime;

namespace Gameplay.PVE
{
    public class PvePrefabPool : ObjectPool<GameObject>
    {
        private ResLoader _resLoader;
        private int _initNum;
        private string _resPath;
        private Transform _root;
        protected GameObject _originObject;

        private Action<GameObject> _completeAction;
        private Action<GameObject> _preLoadComplete;

        private List<Action<GameObject>> _completeActionList = new List<Action<GameObject>>();
        public PveResourceManager.EPveResType PveResType{ get; private set; }
        public bool IsLoaded { get; private set; } = false;

        private List<GameObject> _allObjects = new List<GameObject>();
        
        public PvePrefabPool( PveResourceManager.EPveResType pveResType,int initNum,int capacity,string resPath,Transform root,Action<GameObject> completeAction = null) : 
            base(capacity,true,1,5,10)
        {
#if UNITY_EDITOR
            var strs = resPath.Split('/');
            _name = "PvePrefabPool: " + strs[strs.Length - 1];
#endif
            _completeActionList.Clear();
            _completeAction = completeAction;
            PveResType = pveResType;
            _initNum = initNum;
            _resPath = resPath;
            _root = root;
        }

        
        public void PreLoad(Action<GameObject> preLoadComplete)
        {
            if (IsLoaded)
            {
                preLoadComplete?.Invoke(_originObject);
                return;
            }
            _preLoadComplete = preLoadComplete;
            
            if (_resLoader == null)
            {
                _resLoader = ResLoader.Alloc();
            }
            _resLoader.Add2Load(_resPath, typeof(GameObject), ((success, name, asset) =>
            {
                GameObject tmp = asset as GameObject;
                _originObject = tmp;
                base.OnInit(_initNum);
                IsLoaded = true;
                _completeAction?.Invoke(tmp);
                _preLoadComplete?.Invoke(tmp);
                for (int i = 0; i < _completeActionList.Count; i++)
                {
                    _completeActionList[i]?.Invoke(tmp);
                }
            }));
            _resLoader.Load();
        }
        

        protected override GameObject ConstructItem()
        {
            if (_originObject == null)
            {
                Debug.LogEditorError("PvePrefabPool：资源还未加载完成: " + _resPath);
                return null;
            }
            
            GameObject obj = 
                GameObject.Instantiate(_originObject, GlobalValue.INVISIBLE_POSITION, Quaternion.identity,_root);

            if (PveResType != PveResourceManager.EPveResType.Car)
            {
                // 车辆暂时不使用场景灯光
                var lightElement = obj.GetComponent<LightElement>();
                if (lightElement!=null)
                {
                    if (PveMap.rpgLightController)
                    {
                        PveMap.rpgLightController.AddLightElement(lightElement);
                    }
                }
            }
            

            
            _allObjects.Add(obj);
            return obj;
        }

        public void AddCallBack(Action<GameObject> action)
        {
            if (_originObject == null)
            {
                _completeActionList.Add(action);
            }
            else
            {
                action?.Invoke(_originObject);
            }
        }
        protected override void BeforeRecover(GameObject obj)
        {
            obj.transform.position = GlobalValue.INVISIBLE_POSITION;
            obj.transform.SetParent(_root);
        }

        protected override void OnRemoveItem(GameObject trans)
        {
            GameObject.Destroy(trans);
        }
        
        public override void Destroy()
        {
            // 删除所有子物体
            foreach (var o in _allObjects)
            {
                GameObject.Destroy(o);
            }
            _allObjects.Clear();
            
            _completeActionList.Clear();
            
            base.Destroy();
            if (_resLoader != null)
            {
                _resLoader.Recycle2Cache();
                _resLoader = null;
                _originObject = null;
            }
        }
        
    }
}
